package com.yingxin.yxerp.module.dingtalk.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.aliyun.dingtalkhrm_1_0.Client;
import com.aliyun.dingtalkhrm_1_0.models.QueryDismissionStaffIdListHeaders;
import com.aliyun.dingtalkhrm_1_0.models.QueryDismissionStaffIdListRequest;
import com.aliyun.dingtalkhrm_1_0.models.QueryDismissionStaffIdListResponse;
import com.aliyun.dingtalkhrm_1_0.models.QueryDismissionStaffIdListResponseBody;
import com.aliyun.teaopenapi.models.Config;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.request.OapiSmartworkHrmEmployeeFieldGrouplistRequest;
import com.dingtalk.api.request.OapiSmartworkHrmEmployeeQueryonjobRequest;
import com.dingtalk.api.request.OapiSmartworkHrmEmployeeV2ListRequest;
import com.dingtalk.api.response.OapiSmartworkHrmEmployeeFieldGrouplistResponse;
import com.dingtalk.api.response.OapiSmartworkHrmEmployeeQueryonjobResponse;
import com.dingtalk.api.response.OapiSmartworkHrmEmployeeV2ListResponse;
import com.taobao.api.ApiException;
import com.yingxin.yx.framework.commons.helper.ListHelper;
import com.yingxin.yxerp.module.dingtalk.config.AppConfig;
import com.yingxin.yxerp.module.dingtalk.constant.UrlConstant;
import com.yingxin.yxerp.module.dingtalk.entity.DingFieldMetaInfo;
import com.yingxin.yxerp.module.dingtalk.help.DingUserHelp;
import com.yingxin.yxerp.module.dingtalk.service.IDingUserService;
import com.yingxin.yxerp.module.dingtalk.util.AccessTokenUtil;
import com.yingxin.yxerp.module.dingtalk.vo.DingUserRespVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class DingUserServiceImpl implements IDingUserService {

    @Autowired
    private AppConfig appConfig;

    /**
     * 获取钉钉员工列表
     */
    @Override
    public List<DingUserRespVo> getUserList() throws ApiException {
        // 获取 AccessToken
        String accessToken = AccessTokenUtil.getAccessToken( appConfig.getAppKey(), appConfig.getAppSecret() );
        // 获取 agentId
        Long agentId = Long.parseLong( appConfig.getAppAgentId() );

        // 获取所有字段值
        // String fieldFilterLists = getFieldFilterListToString( getDingFieldMetaInfo( accessToken, agentId ) );

        // 获取在职员工userid列表
        List<String> userIds = getEmployeeQueryonjob( accessToken );

        // 获取在职员工相信信息
        List<DingUserRespVo> dingUserRespVos = getEmployeeList( agentId, accessToken, "", userIds );
        // getEmployeeList( agentId, accessToken, fieldFilterLists, userIds );

        return dingUserRespVos;
        // return null;
    }

    /**
     * 获取花名册字段列表集合
     * @return
     */
    private List<DingFieldMetaInfo> getDingFieldMetaInfo( String accessToken, Long agentid ) throws ApiException {
        DefaultDingTalkClient client = new DefaultDingTalkClient( UrlConstant.GET_EMPLOYEE_FIELD_GROUPLIST_URL );
        OapiSmartworkHrmEmployeeFieldGrouplistRequest req = new OapiSmartworkHrmEmployeeFieldGrouplistRequest();
        req.setAgentid( agentid );
        OapiSmartworkHrmEmployeeFieldGrouplistResponse rsp = client.execute(req, accessToken);

        // 待返回的结果集
        List<DingFieldMetaInfo> dingFieldMetaInfos = new ArrayList<>();

        List<OapiSmartworkHrmEmployeeFieldGrouplistResponse.GroupMetaInfo> groupMetaInfos = rsp.getResult();
        if( CollectionUtil.isNotEmpty( groupMetaInfos ) ){
            for( OapiSmartworkHrmEmployeeFieldGrouplistResponse.GroupMetaInfo groupMetaInfo : groupMetaInfos ){
                List<OapiSmartworkHrmEmployeeFieldGrouplistResponse.FieldMetaInfo> fieldMetaInfos = groupMetaInfo.getFieldList();
                if( CollectionUtil.isNotEmpty( fieldMetaInfos ) ){
                    for( OapiSmartworkHrmEmployeeFieldGrouplistResponse.FieldMetaInfo fieldMetaInfo : fieldMetaInfos ){
                        DingFieldMetaInfo dingFieldMetaInfo = new DingFieldMetaInfo();
                        dingFieldMetaInfo.setFieldCode( fieldMetaInfo.getFieldCode() );
                        dingFieldMetaInfo.setFieldName( fieldMetaInfo.getFieldName() );
                        dingFieldMetaInfo.setFieldType( fieldMetaInfo.getFieldType() );
                        dingFieldMetaInfo.setOptionText( fieldMetaInfo.getOptionText() );

                        dingFieldMetaInfos.add( dingFieldMetaInfo );
                    }
                }
            }
        }

        return dingFieldMetaInfos;
    }

    /**
     * 将花名册字段集合转化为code字符串
     * 如：xxx,xxx,xxx
     * @return
     */
    private String getFieldFilterListToString(List<DingFieldMetaInfo> dingFieldMetaInfos) {
                for ( DingFieldMetaInfo info : dingFieldMetaInfos ){
                    System.out.println("fieldCode = " + info.getFieldCode() +
                            ", fieldName = " + info.getFieldName() +
                            ", fieldType = " + info.getFieldType() +
                            ", optionText = " + info.getOptionText() );
                }
        if( CollectionUtil.isNotEmpty( dingFieldMetaInfos ) ) {
            List<String> list = dingFieldMetaInfos.stream().map(DingFieldMetaInfo::getFieldCode).collect(Collectors.toList());
            return String.join(",", list);
        }
        return "";
    }

    /**
     * 获取在职员工列表
     * 查询企业在职员工userid列表
     * @param accessToken
     * @return
     * @throws ApiException
     */
    private List<String> getEmployeeQueryonjob(String accessToken) throws ApiException {
        DefaultDingTalkClient client = new DefaultDingTalkClient( UrlConstant.GET_EMPLOYEE_QUERYONJOB_URL );
        OapiSmartworkHrmEmployeeQueryonjobRequest req = new OapiSmartworkHrmEmployeeQueryonjobRequest();
        // 2：试用期 3：正式 5：待离职 -1：无状态
        req.setStatusList("2,3,5,-1");
        // req.setStatusList("5");
        req.setSize(50L);

        // 第几页
        Long pageindex = 0L;

        // 员工userid列表
        List<String> userIds = new ArrayList<>();

        while (true){
            req.setOffset( pageindex );
            OapiSmartworkHrmEmployeeQueryonjobResponse rsp = client.execute( req, accessToken );
            if( rsp.getSuccess() ){
                OapiSmartworkHrmEmployeeQueryonjobResponse.PageResult pageResult = rsp.getResult();
                if( ObjectUtil.isNotEmpty( pageResult ) ){
                    List<String> dataLists = pageResult.getDataList();
                    if( CollectionUtil.isNotEmpty( dataLists ) ){
                        userIds.addAll( dataLists );
                    }
                }

                if( pageResult.getNextCursor() != null ){
                    pageindex = pageResult.getNextCursor();
                }else{
                    break;
                }
            }else{
                break;
            }
        }

        if( CollectionUtil.isNotEmpty( userIds ) ){
            return userIds;
        }

        return null;
    }

    /**
     * 获取员工信息列表
     * @param accessToken
     * @param fieldFilterLists
     * @param userIds
     * @return
     * @throws ApiException
     */
    private List<DingUserRespVo> getEmployeeList(Long agentid, String accessToken, String fieldFilterLists, List<String> userIds) throws ApiException {
        DefaultDingTalkClient client = new DefaultDingTalkClient( UrlConstant.GET_EMPLOYEE_LIST_URL );
        OapiSmartworkHrmEmployeeV2ListRequest req = new OapiSmartworkHrmEmployeeV2ListRequest();

        // 待返回的员工列表
        List<DingUserRespVo> users = new ArrayList<>();

        // 分组UserIds
        List<List<String>> pageUserIds = ListHelper.getListSelfSplit( userIds, 100 );
        for( List<String> ids : pageUserIds ){
            // 员工的userid列表，多个userid之间使用逗号分隔，一次最多支持传100个值。
            req.setUseridList( String.join(",", ids) );
            // 不写时查询全部
            // req.setFieldFilterList( fieldFilterLists );
            req.setAgentid( agentid );
            OapiSmartworkHrmEmployeeV2ListResponse rsp = client.execute( req, accessToken );
            if( rsp.getSuccess() ){
                List<OapiSmartworkHrmEmployeeV2ListResponse.EmpRosterFieldVo> empRosterFieldVos = rsp.getResult();
                for( OapiSmartworkHrmEmployeeV2ListResponse.EmpRosterFieldVo empRosterFieldVo : empRosterFieldVos ){
                    // 员工对象
                    DingUserRespVo user = new DingUserRespVo();
                    user.setUserId( empRosterFieldVo.getUserid() );
                    List<OapiSmartworkHrmEmployeeV2ListResponse.EmpFieldDataVo> empFieldDataVos = empRosterFieldVo.getFieldDataList();
                    if( CollectionUtil.isNotEmpty( empFieldDataVos ) ){
                        for( OapiSmartworkHrmEmployeeV2ListResponse.EmpFieldDataVo empFieldDataVo : empFieldDataVos ){
                            DingUserHelp.reflectionUserInfo( user, empFieldDataVo );
                        }
                    }

                    users.add( user );
                }
            }
        }

        return users;
    }

    /**
     * 获取钉钉离职员工列表
     */
    @Override
    public List<DingUserRespVo> getDepartUserList() throws Exception {
        // 获取 AccessToken
        String accessToken = AccessTokenUtil.getAccessToken( appConfig.getAppKey(), appConfig.getAppSecret() );
        // 获取 agentId
        Long agentId = Long.parseLong( appConfig.getAppAgentId() );

        // 待返回的员工列表
        List<String> users = new ArrayList<>();
        Client client = createClient();
        DepartUserList( 0L, users, client, accessToken );

        // 获取离职员工相信信息
        List<DingUserRespVo> dingUserRespVos = getEmployeeList( agentId, accessToken, "", users );

        return dingUserRespVos;
    }

    private Client createClient() throws Exception {
        Config config = new Config();
        config.protocol = "https";
        config.regionId = "central";
        return new Client(config);
    }

    private void DepartUserList(Long nextToken, List<String> users, Client client, String accessToken){
        QueryDismissionStaffIdListHeaders queryDismissionStaffIdListHeaders = new QueryDismissionStaffIdListHeaders();
        queryDismissionStaffIdListHeaders.xAcsDingtalkAccessToken = accessToken;
        QueryDismissionStaffIdListRequest queryDismissionStaffIdListRequest = new QueryDismissionStaffIdListRequest()
                // 分页查询的游标
                .setNextToken( nextToken )
                // 每页条目数
                .setMaxResults(50);

        try {
            QueryDismissionStaffIdListResponse response =
                    client.queryDismissionStaffIdListWithOptions(
                            queryDismissionStaffIdListRequest,
                            queryDismissionStaffIdListHeaders,
                            new com.aliyun.teautil.models.RuntimeOptions() );

            QueryDismissionStaffIdListResponseBody body = response.getBody();

            users.addAll( body.getUserIdList() );

            if (body.getHasMore()){
                DepartUserList( body.getNextToken(), users, client, accessToken );
            }

        }catch(Exception e){

        }
    }

}
